using EntLibContrib.Logging.Install;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
#if !NUNIT
using Microsoft.VisualStudio.TestTools.UnitTesting;
#else
using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
using TestClass = NUnit.Framework.TestFixtureAttribute;
using TestInitialize = NUnit.Framework.SetUpAttribute;
using TestCleanup = NUnit.Framework.TearDownAttribute;
using TestMethod = NUnit.Framework.TestAttribute;
#endif

namespace EntLibContrib.Logging.UnitTests.Install
{
    [TestClass]
    public class LoggingInstallerTest
    {
        public LoggingInstallerTest()
        {
        }

        [ExpectedException(typeof(ArgumentNullException))]
        [TestMethod]
        public void CreateEventLogInstallerWithNullConfigPath()
        {
            LoggingInstaller li = new LoggingInstaller(null);
        }

        [ExpectedException(typeof(ArgumentException))]
        [TestMethod]
        public void CreateInstallerWithInvalidConfigPath()
        {
            string nonExistingFileName = Guid.NewGuid().ToString("N");
            LoggingInstaller li = new LoggingInstaller(nonExistingFileName);
        }

        #if !NUNIT
        [DeploymentItem(@"NoEventLogTraceListeners.config")]
        #endif
        [TestMethod]
        public void UseConfigFileWithNoEventLogTraceListeners()
        {
            string configFile = Path.GetFullPath("NoEventLogTraceListeners.config");
            FakeLoggingInstaller li = new FakeLoggingInstaller(configFile);

            li.SetupEventLogInstallers();

            #if !NUNIT
            Assert.AreEqual<int>(0, li.Installers.Count);
            #else
            Assert.That(li.Installers.Count, Is.EqualTo(0));
            #endif
        }

        #if !NUNIT
        [DeploymentItem(@"SingleEventLogTraceListener.config")]
        #endif
        [TestMethod]
        public void UseConfigFileWithSingleEventLogTraceListener()
        {
            string configFile = Path.GetFullPath("SingleEventLogTraceListener.config");
            FakeLoggingInstaller li = new FakeLoggingInstaller(configFile);

            li.SetupEventLogInstallers();

            #if !NUNIT
            Assert.AreEqual<int>(1, li.Installers.Count);
            Assert.IsInstanceOfType(li.Installers[0], typeof(EventLogInstaller));
            #else
            Assert.That(li.Installers.Count, Is.EqualTo(1));
            Assert.That(li.Installers[0].GetType(), Is.EqualTo(typeof(EventLogInstaller)));
            #endif
            
            EventLogInstaller eli = (EventLogInstaller)li.Installers[0];
            #if !NUNIT
            Assert.AreEqual<string>("Application", eli.Log);
            Assert.AreEqual<string>("Enterprise Library Logging", eli.Source);
            #else
            Assert.That(eli.Log, Is.EqualTo("Application"));
            Assert.That(eli.Source, Is.EqualTo("Enterprise Library Logging"));
            #endif
        }

        #if !NUNIT
        [DeploymentItem(@"TripleEventLogTraceListener.config")]
        #endif
        [TestMethod]
        public void UseConfigFileWithThreeEventLogTraceListeners()
        {
            string configFile = Path.GetFullPath("TripleEventLogTraceListener.config");
            FakeLoggingInstaller li = new FakeLoggingInstaller(configFile);

            li.SetupEventLogInstallers();

            CollectionAssert.AllItemsAreInstancesOfType(li.Installers, typeof(EventLogInstaller));
            
            List<EventLogInstaller> installers = new List<EventLogInstaller>();
            foreach (EventLogInstaller eli in li.Installers)
            {
                installers.Add(eli);
            }

            Assert.IsTrue(installers.TrueForAll(delegate(EventLogInstaller eli) { return eli.Log == "Application"; }));
            Assert.IsTrue(installers.Exists(delegate(EventLogInstaller eli) { return eli.Source == "My Source"; }));
            Assert.IsTrue(installers.Exists(delegate(EventLogInstaller eli) { return eli.Source == "My Other Source"; }));
            Assert.IsTrue(installers.Exists(delegate(EventLogInstaller eli) { return eli.Source == "My Third Source"; }));
        }
    }
}
